/*
 * Copyright (C) 2017-2019 Alibaba Group Holding Limited
 */

/******************************************************************************
 * @file     camera_ov_common.h
 * @brief    head file for camera_ov_common.c
 * @version  V1
 * @date     9. Nov 2019
 ******************************************************************************/
#ifndef _CAMERA_OV_COMMON_H_
#define _CAMERA_OV_COMMON_H_

#include <stdio.h>
#include <string.h>
// #include <csi_config.h>
#include <soc.h>
#include <pin.h>

#define OV_REG_CHIPID_H 0x300A
#define OV_REG_CHIPID_L 0x300B

//define the voltage level of control signal
#define CSI_STBY_ON     1
#define CSI_STBY_OFF    0
#define CSI_RST_ON      0
#define CSI_RST_OFF     1
#define CSI_PWR_ON      1
#define CSI_PWR_OFF     0
#define CSI_AF_PWR_ON   1
#define CSI_AF_PWR_OFF  0

struct regval_list {
    uint16_t addr;
    uint8_t data;
};

enum power_seq_cmd{
    CSI_SUBDEV_PWR_OFF = 0x00,
    CSI_SUBDEV_PWR_ON  = 0x01,
};

#ifdef CONFIG_CHIP_TX216
#define csi_iic_initialize               drv_usi_iic_initialize
#define csi_iic_uninitialize             drv_usi_iic_uninitialize
#define csi_iic_get_capabilities         drv_usi_iic_get_capabilities
#define csi_iic_config                   drv_usi_iic_config
#define csi_iic_master_send              drv_usi_iic_master_send
#define csi_iic_master_receive           drv_usi_iic_master_receive
#define csi_iic_slave_send               drv_usi_iic_slave_send
#define csi_iic_slave_receive            drv_usi_iic_slave_receive
#define csi_iic_abort_transfer           drv_usi_iic_abort_transfer
#define csi_iic_get_status               drv_usi_iic_get_status
#define csi_iic_power_control            drv_usi_iic_power_control
#define csi_iic_config_mode              drv_usi_iic_config_mode
#define csi_iic_config_speed             drv_usi_iic_config_speed
#define csi_iic_config_addr_mode         drv_usi_iic_config_addr_mode
#define csi_iic_config_slave_addr        drv_usi_iic_config_slave_addr
#define csi_iic_get_data_count           drv_usi_iic_get_data_count
#define csi_iic_send_start               drv_usi_iic_send_start
#define csi_iic_send_stop                drv_usi_iic_send_stop
#define csi_iic_reset                    drv_usi_iic_reset
#endif

#define ERR_CAMERA(errno) (CSI_DRV_ERRNO_CAMERA_BASE | errno)
#define CAMERA_NULL_PARAM_CHK(para) HANDLE_PARAM_CHK(para, ERR_CAMERA(DRV_ERROR_PARAMETER))

/**
\brief Camera Status
*/
typedef struct {
    uint32_t pwoer;     ///< Flash busy flag
    uint32_t standby;   ///< Read/Program/Erase error flag (cleared on start of next operation)
} ov_status_t;

/**
\brief Camera information
*/
typedef struct {
    uint32_t pll_clock;    ///< Camera default clock
    uint32_t height;       ///< Camera vertical width
    uint32_t width;        ///< Camera horizontal width
    uint8_t  chipid_high;  ///< Camera Chip ID high byte
    uint8_t  chipid_low;   ///< Camera Chip ID low byte
} ov_base_info_t;

typedef struct {
    int32_t iic_idx;
    iic_handle_t iic_handle;
    uint32_t slave_addr;
    volatile uint8_t cb_transfer_flag;
} ov_commu_info_t;

typedef struct {
    uint8_t init_flag;
    camera_event_cb_t cb;
    ov_base_info_t base_info;
    ov_commu_info_t commu_info;
    ov_status_t status;
    void *user_data;
} ov_priv_t;

int32_t ov_write(ov_commu_info_t *commu_info, uint16_t reg, uint8_t val);
int32_t ov_write_array(ov_commu_info_t *commu_info, struct regval_list *regs, uint32_t array_size);
int32_t ov_read(ov_commu_info_t *commu_info, uint16_t reg, uint8_t *read_data);
int32_t ov_check_id(ov_commu_info_t *commu_info, uint8_t chipid_high, uint8_t chipid_low);
int32_t ov_set_stby(ov_commu_info_t *commu_info, int on_off);
int32_t ov_stream_on(ov_commu_info_t *commu_info);
int32_t ov_stream_off(ov_commu_info_t *commu_info);

#endif // _CAMERA_OV_COMMON_H_
